今天我們來看 Arduino Serial Port 專案中 FTDI driver 的 read method,
public int read(byte[] dest, int timeoutMillis) throws IOException {
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0);
if (ENABLE_ASYNC_READS) { // 基本上 android 不支援 ASYNC 傳輸,這段可以略過不看
final int readAmt;
synchronized (mReadBufferLock) {
// mReadBuffer is only used for maximum read size.
readAmt = Math.min(dest.length, mReadBuffer.length);
}
final UsbRequest request = new UsbRequest();
request.initialize(mConnection, endpoint);
final ByteBuffer buf = ByteBuffer.wrap(dest);
if (!request.queue(buf, readAmt)) {
throw new IOException("Error queueing request.");
}
final UsbRequest response = mConnection.requestWait();
if (response == null) {
throw new IOException("Null response");
}
final int payloadBytesRead = buf.position() - MODEM_STATUS_HEADER_LENGTH;
if (payloadBytesRead > 0) {
Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
return payloadBytesRead;
} else {
return 0;
}
} else {
final int totalBytesRead;
synchronized (mReadBufferLock) {
final int readAmt = Math.min(dest.length, mReadBuffer.length);
totalBytesRead = mConnection.bulkTransfer(endpoint, mReadBuffer,
readAmt, timeoutMillis); // 呼叫 bulkTransfer
if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) {
throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes");
}
return filterStatusBytes(mReadBuffer, dest, totalBytesRead, endpoint.getMaxPacketSize());
}
}
}
由上面可以知道,由 usb serial port 讀資料的重頭戲其實就落在 bulkTransfer ,bulkTransfer 是什麼東西?
從這邊: http://developer.android.com/reference/android/hardware/usb/UsbDeviceConnection.html
可以知道 bulkTransfer 主要負責 USB 資料傳輸的角色,當我們 dest[] 為空的時候,bulkTransfer 會自動幫我們「讀」資料近來。
反之 dest[] 有資料時,bulkTransfer 就會試著幫我們把資料送出去。他的傳入參數分別是:
而bulkTransfer 眾多參數中除了 buffer 資料的方式之外,就是 endpoint 了,endpoint 的進一步資料可以參考 Fred 的:http://fred-zone.blogspot.tw/2009/08/usb_10.html
由上述資訊,我們可以先推測 app 收不到資料,可能是選擇 endpoint 的環節出問題了
我們明天見